﻿/****************
 * Copyright 2016 Brian Tabone
 * Licensed under the Apache 2.0 License
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Program.cs
 * Main program module for the 3D world
 * 9/10/2016
 */

using System;
using System.Configuration;
using System.Net.NetworkInformation;
using System.Reflection;
using IAO.Common.Interfaces.Networking;
using IAO.Common.Network;
using IAO.Common.Network.MessageControllers;
using IAO.Common.ServiceFramework;
using IAO.Common.ServiceFramework.RuntimeProperties;
using log4net;
using log4net.Config;
using World3D.DataAccessLayer;
using World3D.PropertyInitalizers;

[assembly: XmlConfigurator(Watch = true)]

namespace World3D
{
    internal class Program
    {
        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        private static Uri _endpoint;
        private static IMessageChannel _msgChannel;
        private static PropertyManager _propertyManager;
        private static World3DDal _dal;

        private static void Main(string[] args)
        {
            Log.Info(
                $"Starting {Assembly.GetExecutingAssembly().GetName().Name} {Assembly.GetExecutingAssembly().GetName().Version}");

            _dal = new World3DDal(Log);
            _endpoint = new Uri(ConfigurationManager.AppSettings["World3DEndpoint"]);

            InitializePropertyManager();
            InitializeProperties();
            InitializeMessageChannel();

            Console.ReadLine();
            _msgChannel.StopListening();
        }

        private static void InitializeMessageChannel()
        {
            _msgChannel = new MessageChannel(_endpoint.Host, (ushort) _endpoint.Port);
            _msgChannel.StartListening();
            Log.Info($"Message Channel started on {_msgChannel.Host}:{_msgChannel.Port}");
            Console.WriteLine("Press enter to stop");
        }

        /// <summary>
        ///     Setup the properties
        /// </summary>
        private static void InitializeProperties()
        {
            _propertyManager.AddProperty(new VolatileProperty(1, "System", "Endpoint", _endpoint.ToString(), typeof(string).ToString(),
                true));
            _propertyManager.AddProperty(new VolatileProperty(2, "System", "Application", Assembly.GetExecutingAssembly().Location,
                typeof(string).ToString(), true));
            _propertyManager.AddProperty(new UptimeProperty(3));
            _propertyManager.AddPersistentPropertyIfNotExists(new TestProperty(4, "Test", "TestSetter", "Word3DTestProp1",
                typeof(string).ToString(), false));
            _propertyManager.AddPersistentPropertyIfNotExists(new TestProperty(5, "Test", "TestIntSet", "-4000", typeof(int).ToString(), false));

            PhysicsPropertiesInitializer.InitializeOnManager(_propertyManager);
        }

        /// <summary>
        ///     Setup the property manager and attach the data access layer to it
        /// </summary>
        private static void InitializePropertyManager()
        {
            _propertyManager = PropertyManager.GetPropertyManager;
            _propertyManager.SetDataAccessLayer(_dal);

            PropertiesController.GetPropertiesEvent += _propertyManager.PropertiesController_GetPropertiesEvent;
            PropertiesController.SetPropertiesEvent += _propertyManager.PropertiesController_SetPropertiesEvent;
        }
    }
}